﻿using Kinlo.Entitys;
using Kinlo.MESDocking;
using NPOI.SS.Formula.Functions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using UIWindows.GlobalStatics;
using UIWindows.Services.Context;
using UIWindows.Tools.Helper;
using XingLucifer.Devices;
using XingLucifer.IBase.Enums;
using XingLucifer.IBase.Models.PLCInteraktion;

namespace UIWindows.Services.Handle
{
    [Attributes.TaskClass(TaskTypes.补液称)]
    public class RefillWeighing : ServierBase
    {

        static object locker = new object();
        public RefillWeighing(DeviceConfigStatic deviceConfig, SystemConfigStatic systemConfig,
            UserConfigStatic userConfig, ParameterStatic parameterStatic, TemporaryStatic temporaryStatic, HomeStatic homeStatic, MesParameterStatic mesParameterStatic)
            : base(deviceConfig, systemConfig, userConfig, parameterStatic, temporaryStatic, homeStatic, mesParameterStatic)
        {
            _interaction = new ProduceOpenAddInterface(DialogLogHelper.MesLog, DialogLogHelper.MESDialog);
        }

        public override Task Handle(DataContext context)
        {
            if (!ClearSignal(context)) { return Task.CompletedTask; }
            try
            {
                var plc = _deviceConfig.DeviceList.FirstOrDefault(x => x.ServiceName == context.ServiceName && x.TaskType == TaskTypes.扫描信号).Communication as OmronCIP;
                DateTime weighing_time = DateTime.Now;
                var erinnerungen = ReadErinnerungen(plc, context.Address_Struct, context.Struct_Length, _systemConfig.IAddress.Erinnerungen_RehydrationVolume, context.AddressingMethod);
                if (erinnerungen.Item1)
                {
                    $"==>>{context.TaskType}<<==\r\n收到启动信号，没收到电池记忆，请联系电气工程师！！！".MessageDialogs(MessageLevelType.错误, false, Enums.PopUpTypes.Global);
                    return base.Handle(context);
                }
                RunLog($"记忆ID：{string.Join(";", erinnerungen.Item2.Select(x => x.SnowflakeId))}");
                bool alarm = false;
                int _lessLiquid = 0;
                Parallel.ForEach(erinnerungen.Item2, battery =>
                        {
                            if (battery.SnowflakeId == 0) { return; }
                            Models.Devices.DeviceClientModel? device = _deviceConfig.DeviceList.FirstOrDefault(x => x.ServiceName == context.ServiceName && x.TaskType == context.TaskType
                            && x.DeviceType == context.DeviceType && x.Index == battery.Index);
                            if (device == null)
                            {
                                RunLog($"找不到[{battery.Index}]号设备", MessageLevelType.错误);
                                WriteResult("", ResultTypes.不合格, plc, battery.Address_Struct, context);
                                return;
                            }
                            double? weiging = default;
                            if (battery.SnowflakeId == -1)
                            {
                                weiging = GetWeiging(device, "点检");
                                RunLog($"-[{battery.Index}] 点检重量：{weiging} g");
                                if (weiging == null)
                                {
                                    WriteResult("", ResultTypes.不合格, plc, battery.Address_Struct, context);
                                    return;
                                }
                                WriteResult("", (weiging >= _parameterStatic.RangeParameter.SpotCheck_WeighingDown && weiging <= _parameterStatic.RangeParameter.SpotCheck_WeighingUp) ? ResultTypes.合格 : ResultTypes.不合格, plc, battery.Address_Struct, context);
                                return;
                            }
                            DateTime dateTime = DateTime.Now;
                            ProductionData? entity = _temporaryStatic.EntityCache.FirstOrDefault(x => x.SnowflakeId == battery.SnowflakeId);
                            if (entity == null)
                            {
                                RunLog($"-[{battery.Index}] 实体缓存查询不到==>[{battery.SnowflakeId}]，转到数据库查询");
                                entity = dateTime.GetEntity(context.TaskType, battery.SnowflakeId);
                            }
                            else
                            {
                                ProductionData.Meta.TableName = entity.Items["TableName"].ToString();
                            }
                            if (entity == null)
                            {
                                RunLog($"-[{battery.Index}] 数据库找不到ID为：{battery.SnowflakeId}");
                                WriteResult("", ResultTypes.数据库找不到电池, plc, battery.Address_Struct, context);
                                return;
                            }
                            RunLog($"-[{battery.Index}] ID：[{battery.SnowflakeId}] 条码：[{entity.BarCode}]");

                            bool _isReduce = entity.ResultAfterWeighing == ResultTypes.注液量偏少 && entity.ResultRefillWeighing != ResultTypes.合格;

                            entity.TimeRehydrationWeighing = weighing_time.GetJSTimeUtc();
                            weiging = GetWeiging(device, entity.BarCode);
                            if ((weiging == null || weiging < 20) && !_parameterStatic.DecideParameter.EnableEmptyRun)
                            {
                                RunLog($"[{entity.BarCode}] [{battery.Index}]号不稳定报警", MessageLevelType.警告);
                                alarm = true;
                            }

                            entity.RehydrationWeighing = weiging == null ? 0 : (double)weiging;
                            entity.FluidRateReplenish = Math.Round(entity.RehydrationWeighing - entity.AfterWeighing, 1, MidpointRounding.AwayFromZero);
                            entity.ActualTotalInjectionVolume = Math.Round(entity.RehydrationWeighing - entity.NetWeight, 2, MidpointRounding.AwayFromZero);
                            if (_systemConfig.SCM.MainDeviceType == MainDeviceTypeEnum.一次注液)
                                entity.OneAfterWeighing = entity.RehydrationWeighing;
                            entity.ResultRefillWeighing = InjRange_Check(entity, 2);

                            if (_isReduce && entity.ResultRefillWeighing == ResultTypes.合格)
                            {
                                Interlocked.Increment(ref _lessLiquid);
                            }

                            if (entity.ResultRefillWeighing == ResultTypes.注液量偏少) //写补液量
                            {
                                var refillInj = (float)Math.Abs(entity.TotalInjectionVolumeDeviationValue);
                                if (!WriteInjectionVolume(refillInj, plc, battery.Address_Struct, context))
                                {
                                    entity.ResultRefillWeighing = ResultTypes.注液量写入失败;
                                }
                            }
                            //if (entity.ResultRefillWeighing != ResultTypes.合格 && entity.ResultTotal == ResultTypes._)
                                entity.ResultTotal = entity.ResultRefillWeighing;

                            try
                            {
                                entity.Update();

                            }
                            catch (Exception ex)
                            {
                                RunLog($"-[{battery.Index}] 数据库保存异常：{ex}");
                            }

                            #region MES 出站
                            if (_parameterStatic.DecideParameter.EnableMES)
                            {
                                if ((int)entity.ResultTotal < 2)//OK出站
                                {
                                    if (_systemConfig.SCM.OutputProcesses == OutputProcessesEnum.后称)
                                        BatteryOutboundDataUpload(_interaction, entity);
                                }
                                else
                                {
                                    //BatteryOutboundDataUpload(_interaction, entity, false, "不合格");//NG出站
                                    BatteryOutboundDataUpload(_interaction, entity, false, entity.ResultTotal.ToString());//NG出站
                                }
                            }
                            #endregion

                            WriteResult(entity.BarCode, entity.ResultRefillWeighing, plc, battery.Address_Struct, context);
                            _homeStatic.AddOutBattery(entity);

                            #region 补液合格后，修改注液合格率
                            lock (locker)
                            {
                                _homeStatic.ChartData.NG_LessLiquid -= _lessLiquid;
                                _homeStatic.ChartData.OV_LessLiquid.Value = _homeStatic.ChartData.NG_LessLiquid;
                                _homeStatic.ChartData.NG_LiquidInjection -= _lessLiquid;
                                var _passingRate = Math.Round((_homeStatic.ChartData.Total_LiquidInjection - (_homeStatic.ChartData.NG_MultiLiquid + _homeStatic.ChartData.NG_LessLiquid)) / _homeStatic.ChartData.Total_LiquidInjection, 4, MidpointRounding.ToNegativeInfinity);
                                _homeStatic.ChartData.LiquidInjection_PassingRate = _passingRate > 1 ? 1 : _passingRate;
                                _homeStatic.ChartData.OV_LiquidInjection_PassingRate.Value = _homeStatic.ChartData.LiquidInjection_PassingRate;
                                _lessLiquid = 0;
                            }
                            #endregion


                        });
                if (alarm) { WriteCMD(1, plc, _systemConfig.IAddress.Alarm_RefillWeighing); }
            }
            catch (Exception ex)
            {
                RunLog($"异常：{ex}");
            }
            return base.Handle(context);
        }


    }
}
